package cn.net.yugu.doraemon.common.dal.repository;

import java.util.List;
import java.util.Optional;

/**
 * 支持常规 CRUD 操作
 *
 * @param <ID> 表主键
 * @param <Q>  查询类类型
 * @param <T>  实体类类型
 * @author xiangzr
 * @version 2023/4/1 8:52:06
 */
public interface CrudRepository<T, ID, Q> extends Repository<T, ID> {


    /**
     * 保存给定实体。使用返回的实例进行进一步的操作，因为保存操作可能已更改 完全实体实例。
     *
     * @param entity 不能为 {@literal null}.
     * @return 被保存的实体; 永不为 {@literal null}.
     * @throws IllegalArgumentException 当输入的 {@literal entity} 是 {@literal null}.
     */
    <S extends T> S save(S entity);

    /**
     * 保存所有给定的实体
     *
     * @param entities 不能为 {@literal null} 也不能包含 {@literal null} 元素.
     * @return 保存的实体; 永不为 {@literal null}. 返回的 {@literal Iterable} 将是与输入 {@literal Iterable} 参数相同大小的
     * @throws IllegalArgumentException 当输入的 {@link Iterable entities} 或其中的存在元素 {@literal null} 时抛出
     */
    <S extends T> List<S> saveAll(List<S> entities);

    /**
     * 按实体的 ID 检索实体。
     *
     * @param id 不能为 {@literal null}.
     * @return 返回id 对应的实体，或 {@literal Optional#empty()}
     * @throws IllegalArgumentException 若 {@literal id} 是 {@literal null} 时抛出
     */
    Optional<T> findById(ID id);

    /**
     * 范围是否存在id为输入参数的实体
     *
     * @param id 不能为 {@literal null}.
     * @return 存在时 {@literal true} ，其他情况返回 {@literal false}
     * @throws IllegalArgumentException 当 {@literal id} 为 {@literal null} 时抛出
     */
    boolean existsById(ID id);

    /**
     * 根据参数更新
     *
     * @param id 不能为 {@literal null}.
     * @return 更新成功 true ，其他情况(含记录不存在时) false
     */
    boolean updateById(ID id);

    /**
     * 根据多个id值查询多个实体
     *
     * @param ids 不能为 {@literal null} 且不能包含任何为 {@literal null} 的值。
     * @return 不会为 {@literal null}. 数量小于等于给定{@literal ids}的集合
     * @throws IllegalArgumentException 输入的 {@link Iterable ids} 或其中的元素值为 {@literal null}时抛出
     */
    default List<T> findAllById(List<ID> ids) {
        throw new UnsupportedOperationException();
    }

    /**
     * 根据id删除
     * <p>
     * 如果在暂留存储中找不到该实体，则会以静默方式忽略该实体。
     * (id对应的实体不存在时，也认为删除成功）
     *
     * @param id 不能为 {@literal null}.
     * @throws IllegalArgumentException 当 {@literal id} 为 {@literal null}时
     */
    default void deleteById(ID id) {
        throw new UnsupportedOperationException();
    }

    /**
     * 删除多个输入id 的实体 {@code T}
     * <p>
     * 如果在暂留存储中找不到该实体，则会以静默方式忽略该实体。
     * * (id对应的实体不存在时，也认为删除成功）
     *
     * @param ids 不能为 {@literal null}. 不能包含 {@literal null} 元素
     * @throws IllegalArgumentException {@literal ids} 或其中的元素为 {@literal null}.
     */
    default void deleteAllById(List<? extends ID> ids) {
        throw new UnsupportedOperationException();
    }


    /**
     * 根据查询条件（Query) 获取记录数
     *
     * @return the number of entities.
     */
    default long count(Q query) {
        throw new UnsupportedOperationException();
    }

    /**
     * 根据查询条件（Query) 获取实体集合
     *
     * @param query
     * @return
     */
    default List<T> findAll(Q query) {
        throw new UnsupportedOperationException();
    }

}
